diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +

+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/casic/dcms/ExampleUnitTest.java b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java new file mode 100644 index 0000000..66ab075 --- /dev/null +++ b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.casic.dcms; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/casic/dcms/ExampleUnitTest.java b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java new file mode 100644 index 0000000..66ab075 --- /dev/null +++ b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.casic.dcms; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..96af85d --- /dev/null +++ b/build.gradle @@ -0,0 +1,45 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + + } + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + maven { url 'https://jitpack.io' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + authentication { + basic(BasicAuthentication) + } + credentials { + // Do not change the username below. + // This should always be `mapbox` (not your username). + username = 'mapbox' + // Use the secret token you stored in gradle.properties as the password + password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: "" + } + } + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/casic/dcms/ExampleUnitTest.java b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java new file mode 100644 index 0000000..66ab075 --- /dev/null +++ b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.casic.dcms; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..96af85d --- /dev/null +++ b/build.gradle @@ -0,0 +1,45 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + + } + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + maven { url 'https://jitpack.io' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + authentication { + basic(BasicAuthentication) + } + credentials { + // Do not change the username below. + // This should always be `mapbox` (not your username). + username = 'mapbox' + // Use the secret token you stored in gradle.properties as the password + password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: "" + } + } + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..80e2630 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,20 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true +MAPBOX_DOWNLOADS_TOKEN=pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/casic/dcms/ExampleUnitTest.java b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java new file mode 100644 index 0000000..66ab075 --- /dev/null +++ b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.casic.dcms; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..96af85d --- /dev/null +++ b/build.gradle @@ -0,0 +1,45 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + + } + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + maven { url 'https://jitpack.io' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + authentication { + basic(BasicAuthentication) + } + credentials { + // Do not change the username below. + // This should always be `mapbox` (not your username). + username = 'mapbox' + // Use the secret token you stored in gradle.properties as the password + password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: "" + } + } + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..80e2630 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,20 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true +MAPBOX_DOWNLOADS_TOKEN=pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar Binary files differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/casic/dcms/ExampleUnitTest.java b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java new file mode 100644 index 0000000..66ab075 --- /dev/null +++ b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.casic.dcms; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..96af85d --- /dev/null +++ b/build.gradle @@ -0,0 +1,45 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + + } + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + maven { url 'https://jitpack.io' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + authentication { + basic(BasicAuthentication) + } + credentials { + // Do not change the username below. + // This should always be `mapbox` (not your username). + username = 'mapbox' + // Use the secret token you stored in gradle.properties as the password + password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: "" + } + } + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..80e2630 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,20 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true +MAPBOX_DOWNLOADS_TOKEN=pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar Binary files differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7754394 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Apr 06 11:01:36 CST 2021 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/casic/dcms/ExampleUnitTest.java b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java new file mode 100644 index 0000000..66ab075 --- /dev/null +++ b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.casic.dcms; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..96af85d --- /dev/null +++ b/build.gradle @@ -0,0 +1,45 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + + } + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + maven { url 'https://jitpack.io' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + authentication { + basic(BasicAuthentication) + } + credentials { + // Do not change the username below. + // This should always be `mapbox` (not your username). + username = 'mapbox' + // Use the secret token you stored in gradle.properties as the password + password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: "" + } + } + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..80e2630 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,20 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true +MAPBOX_DOWNLOADS_TOKEN=pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar Binary files differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7754394 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Apr 06 11:01:36 CST 2021 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/casic/dcms/ExampleUnitTest.java b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java new file mode 100644 index 0000000..66ab075 --- /dev/null +++ b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.casic.dcms; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..96af85d --- /dev/null +++ b/build.gradle @@ -0,0 +1,45 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + + } + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + maven { url 'https://jitpack.io' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + authentication { + basic(BasicAuthentication) + } + credentials { + // Do not change the username below. + // This should always be `mapbox` (not your username). + username = 'mapbox' + // Use the secret token you stored in gradle.properties as the password + password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: "" + } + } + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..80e2630 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,20 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true +MAPBOX_DOWNLOADS_TOKEN=pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar Binary files differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7754394 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Apr 06 11:01:36 CST 2021 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..5cd135a --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7bfef59 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ca3f486 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "com.casic.dcms" + minSdkVersion 21 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + //Google官方授权框架 + implementation 'pub.devrel:easypermissions:1.3.0' + //腾讯Android UI框架 + implementation 'com.qmuiteam:qmui:2.0.0-alpha10' + implementation 'com.qmuiteam:arch:0.3.1' + //MVP控件注解 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //图片加载框架 + implementation 'com.github.bumptech.glide:glide:4.5.0' + //MVP网络请求框架retrofit2+rxjava + 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.okhttp3:okhttp:4.6.0' + implementation 'com.squareup.retrofit2:converter-gson:2.8.1' + implementation 'com.squareup.retrofit2:adapter-rxjava:2.8.1' + implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0' + //官方Json解析库 + implementation 'com.google.code.gson:gson:2.8.6' + //图片选择框架 + implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' + //视频播放器 + implementation 'fm.jiecao:jiecaovideoplayer:5.5.4' + //全球可用地图MapBox + implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.2.1' + implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /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 diff --git a/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d8faada --- /dev/null +++ b/app/src/androidTest/java/com/casic/dcms/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.casic.dcms; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.casic.dcms", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7651c6f --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java new file mode 100644 index 0000000..f036dfb --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/HomeRecycleAdapter.java @@ -0,0 +1,75 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.casic.dcms.R; +import com.casic.dcms.utils.Constant; + +public class HomeRecycleAdapter extends RecyclerView.Adapter { + + private Context context; + + public HomeRecycleAdapter(Context context) { + this.context = context; + } + + @NonNull + @Override + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(context).inflate(R.layout.item_home_recycleview, parent, false); + return new ItemViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { + holder.bindView(context, position); + if (clickListener != null) { + holder.itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + } + + @Override + public int getItemCount() { + return Constant.ITEMS.size(); + } + + private OnGridItemClickListener clickListener; + + public interface OnGridItemClickListener { + void onClick(int position); + } + + public void setOnGridItemClickListener(OnGridItemClickListener onGridItemClickListener) { + this.clickListener = onGridItemClickListener; + } + + static class ItemViewHolder extends RecyclerView.ViewHolder { + + private ImageView imageView; + private TextView textView; + + ItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = itemView.findViewById(R.id.imageView); + textView = itemView.findViewById(R.id.textView); + } + + void bindView(Context context, int position) { + imageView.setBackgroundResource(Constant.ICONS.get(position)); + textView.setText(Constant.ITEMS.get(position)); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java new file mode 100644 index 0000000..5ac7a3b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/ImageGridViewAdapter.java @@ -0,0 +1,87 @@ +package com.casic.dcms.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.casic.dcms.R; +import com.luck.picture.lib.entity.LocalMedia; + +import java.util.List; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 17:17 + * @Emain: 290677893@qq.com + **/ +public class ImageGridViewAdapter extends BaseAdapter { + + private static final String TAG = "ImageGridViewAdapter"; + private Context context; + private List mediaList; + private LayoutInflater inflater; + + public ImageGridViewAdapter(Context mContext, List selectList) { + this.context = mContext; + this.mediaList = selectList; + inflater = LayoutInflater.from(context); + } + + @Override + public int getCount() { + return mediaList == null ? 0 : mediaList.size(); + } + + @Override + public Object getItem(int position) { + return mediaList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder itemViewHolder; + if (convertView == null) { + convertView = inflater.inflate(R.layout.item_select_gridview, null); + itemViewHolder = new ItemViewHolder(); + itemViewHolder.imageView = convertView.findViewById(R.id.imageView); + itemViewHolder.deleteView = convertView.findViewById(R.id.deleteView); + convertView.setTag(itemViewHolder); + } else { + itemViewHolder = (ItemViewHolder) convertView.getTag(); + } + Glide.with(context).load(mediaList.get(position).getRealPath()).into(itemViewHolder.imageView); + if (clickListener != null) { + itemViewHolder.deleteView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clickListener.onClick(position); + } + }); + } + return convertView; + } + + private static class ItemViewHolder { + private ImageView imageView; + private ImageView deleteView; + } + + private OnDeleteItemClickListener clickListener; + + public interface OnDeleteItemClickListener { + void onClick(int position); + } + + public void setOnDeleteClickListener(OnDeleteItemClickListener deleteItemClickListener) { + this.clickListener = deleteItemClickListener; + } +} diff --git a/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java new file mode 100644 index 0000000..34195af --- /dev/null +++ b/app/src/main/java/com/casic/dcms/adapter/MainPageAdapter.java @@ -0,0 +1,29 @@ +package com.casic.dcms.adapter; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; + +import java.util.List; + +public class MainPageAdapter extends FragmentPagerAdapter { + + private List fragmentList; + + public MainPageAdapter(@NonNull FragmentManager fm, List pages) { + super(fm); + this.fragmentList = pages; + } + + @NonNull + @Override + public Fragment getItem(int position) { + return fragmentList.get(position); + } + + @Override + public int getCount() { + return fragmentList.size(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseActivity.java b/app/src/main/java/com/casic/dcms/base/BaseActivity.java new file mode 100644 index 0000000..9213f3c --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseActivity.java @@ -0,0 +1,46 @@ +package com.casic.dcms.base; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.R; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; + +import butterknife.ButterKnife; + +public abstract class BaseActivity extends AppCompatActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(initLayoutView()); + ButterKnife.bind(this); + QMUIStatusBarHelper.translucent(this);//沉浸式状态栏 + setupTopBarLayout(); + initData(); + initEvent(); + } + + /** + * 初始化xml布局 + */ + public abstract int initLayoutView(); + + /** + * 特定页面定制沉浸式状态栏 + */ + protected abstract void setupTopBarLayout(); + + /** + * 初始化默认数据 + */ + public abstract void initData(); + + /** + * 初始化业务逻辑 + */ + public abstract void initEvent(); +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseApplication.java b/app/src/main/java/com/casic/dcms/base/BaseApplication.java new file mode 100644 index 0000000..6150788 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseApplication.java @@ -0,0 +1,19 @@ +package com.casic.dcms.base; + +import android.app.Application; + +import com.casic.dcms.R; +import com.casic.dcms.utils.SaveKeyValues; +import com.mapbox.mapboxsdk.Mapbox; +import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager; + +public class BaseApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + QMUISwipeBackActivityManager.init(this); + SaveKeyValues.initSharedPreferences(this); + //MapBox地图注册 + Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/BaseFragment.java b/app/src/main/java/com/casic/dcms/base/BaseFragment.java new file mode 100644 index 0000000..ed6949b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/BaseFragment.java @@ -0,0 +1,45 @@ +package com.casic.dcms.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import butterknife.ButterKnife; +import butterknife.Unbinder; + +public abstract class BaseFragment extends Fragment { + + private Unbinder bind; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(initLayoutView(), container, false); + bind = ButterKnife.bind(this, view); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + initEvent(); + } + + protected abstract int initLayoutView(); + + protected abstract void initData(); + + protected abstract void initEvent(); + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind.unbind(); + } +} diff --git a/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java new file mode 100644 index 0000000..6fc764e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/base/DoubleClickExitActivity.java @@ -0,0 +1,23 @@ +package com.casic.dcms.base; + +import android.view.KeyEvent; +import android.widget.Toast; + +public abstract class DoubleClickExitActivity extends BaseActivity { + + private long clickTime = 0; + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (System.currentTimeMillis() - clickTime > 2000) { + Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); + clickTime = System.currentTimeMillis(); + return true; + } else { + return super.onKeyDown(keyCode, event); + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java new file mode 100644 index 0000000..b3b1e44 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/LoginResultBean.java @@ -0,0 +1,74 @@ +package com.casic.dcms.bean; + +public class LoginResultBean { + + /** + * code : 200 + * data : {"kaptcha":"","token":"e2dc5885-c830-4773-ba63-9f6f4efdc0fd"} + * message : 登录成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * kaptcha : + * token : e2dc5885-c830-4773-ba63-9f6f4efdc0fd + */ + + private String kaptcha; + private String token; + + public String getKaptcha() { + return kaptcha; + } + + public void setKaptcha(String kaptcha) { + this.kaptcha = kaptcha; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java new file mode 100644 index 0000000..1298cd3 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/PublicKeyBean.java @@ -0,0 +1,97 @@ +package com.casic.dcms.bean; + +/** + * PublicKey 登录校验Key + */ +public class PublicKeyBean { + + /** + * code : 200 + * data : {"appKaptcha":false,"kaptcha":false,"publicKey":"","sid":"a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d"} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * appKaptcha : false + * kaptcha : false + * publicKey : + * sid : a084d9c0-6ac5-46f4-b9d7-b6edabb31b6d + */ + + private boolean appKaptcha; + private boolean kaptcha; + private String publicKey; + private String sid; + + public boolean isAppKaptcha() { + return appKaptcha; + } + + public void setAppKaptcha(boolean appKaptcha) { + this.appKaptcha = appKaptcha; + } + + public boolean isKaptcha() { + return kaptcha; + } + + public void setKaptcha(boolean kaptcha) { + this.kaptcha = kaptcha; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getSid() { + return sid; + } + + public void setSid(String sid) { + this.sid = sid; + } + } +} diff --git a/app/src/main/java/com/casic/dcms/bean/UserBean.java b/app/src/main/java/com/casic/dcms/bean/UserBean.java new file mode 100644 index 0000000..31ec3a0 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/bean/UserBean.java @@ -0,0 +1,422 @@ +package com.casic.dcms.bean; + +import java.util.List; + +public class UserBean { + + /** + * code : 200 + * data : {"account":"cgjd01","attr1":"","avatar":"","bizData":"","dataScope":["1177026995528237058"],"deptId":"1177026995528237058","deptName":"指挥中心","devices":[{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}],"id":"1177050541084160002","ipAddr":"111.198.10.15","name":"王金龙","phone":"18600202669","roleList":["1177029183042322434"],"roleNames":["监督员"],"roleTips":["supervisor"],"scopeType":"4","sysData":"","targetId":"","targetName":"","tenantId":""} + * message : 请求成功 + * success : true + */ + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + /** + * account : cgjd01 + * attr1 : + * avatar : + * bizData : + * dataScope : ["1177026995528237058"] + * deptId : 1177026995528237058 + * deptName : 指挥中心 + * devices : [{"account":"","deptId":"","deptName":"","deviceName":"12345","id":"1349258555972796417","imei":"1234","lastTime":"2021-01-13","lastTimeFmt":"","name":"","networkNumber":"1234","onLine":false,"phone":"","positionLat":"","positionLng":"","targetId":"","userId":"1177050541084160002"}] + * id : 1177050541084160002 + * ipAddr : 111.198.10.15 + * name : 王金龙 + * phone : 18600202669 + * roleList : ["1177029183042322434"] + * roleNames : ["监督员"] + * roleTips : ["supervisor"] + * scopeType : 4 + * sysData : + * targetId : + * targetName : + * tenantId : + */ + + private String account; + private String attr1; + private String avatar; + private String bizData; + private String deptId; + private String deptName; + private String id; + private String ipAddr; + private String name; + private String phone; + private String scopeType; + private String sysData; + private String targetId; + private String targetName; + private String tenantId; + private List dataScope; + private List devices; + private List roleList; + private List roleNames; + private List roleTips; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAttr1() { + return attr1; + } + + public void setAttr1(String attr1) { + this.attr1 = attr1; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getBizData() { + return bizData; + } + + public void setBizData(String bizData) { + this.bizData = bizData; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getIpAddr() { + return ipAddr; + } + + public void setIpAddr(String ipAddr) { + this.ipAddr = ipAddr; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getScopeType() { + return scopeType; + } + + public void setScopeType(String scopeType) { + this.scopeType = scopeType; + } + + public String getSysData() { + return sysData; + } + + public void setSysData(String sysData) { + this.sysData = sysData; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public List getDataScope() { + return dataScope; + } + + public void setDataScope(List dataScope) { + this.dataScope = dataScope; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getRoleNames() { + return roleNames; + } + + public void setRoleNames(List roleNames) { + this.roleNames = roleNames; + } + + public List getRoleTips() { + return roleTips; + } + + public void setRoleTips(List roleTips) { + this.roleTips = roleTips; + } + + public static class DevicesBean { + /** + * account : + * deptId : + * deptName : + * deviceName : 12345 + * id : 1349258555972796417 + * imei : 1234 + * lastTime : 2021-01-13 + * lastTimeFmt : + * name : + * networkNumber : 1234 + * onLine : false + * phone : + * positionLat : + * positionLng : + * targetId : + * userId : 1177050541084160002 + */ + + private String account; + private String deptId; + private String deptName; + private String deviceName; + private String id; + private String imei; + private String lastTime; + private String lastTimeFmt; + private String name; + private String networkNumber; + private boolean onLine; + private String phone; + private String positionLat; + private String positionLng; + private String targetId; + private String userId; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getDeptId() { + return deptId; + } + + public void setDeptId(String deptId) { + this.deptId = deptId; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getImei() { + return imei; + } + + public void setImei(String imei) { + this.imei = imei; + } + + public String getLastTime() { + return lastTime; + } + + public void setLastTime(String lastTime) { + this.lastTime = lastTime; + } + + public String getLastTimeFmt() { + return lastTimeFmt; + } + + public void setLastTimeFmt(String lastTimeFmt) { + this.lastTimeFmt = lastTimeFmt; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNetworkNumber() { + return networkNumber; + } + + public void setNetworkNumber(String networkNumber) { + this.networkNumber = networkNumber; + } + + public boolean isOnLine() { + return onLine; + } + + public void setOnLine(boolean onLine) { + this.onLine = onLine; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPositionLat() { + return positionLat; + } + + public void setPositionLat(String positionLat) { + this.positionLat = positionLat; + } + + public String getPositionLng() { + return positionLng; + } + + public void setPositionLng(String positionLng) { + this.positionLng = positionLng; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java new file mode 100644 index 0000000..b3e7d1e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/BasePresenter.java @@ -0,0 +1,23 @@ +package com.casic.dcms.mvp; + +import rx.Subscription; +import rx.subscriptions.CompositeSubscription; + +public class BasePresenter { + private CompositeSubscription mCompositeSubscription; + + //RxJava注册 + protected void addSubscription(Subscription subscriber) { + if (mCompositeSubscription == null) { + mCompositeSubscription = new CompositeSubscription(); + } + mCompositeSubscription.add(subscriber); + } + + //RxJava取消注册,以避免内存泄露 + protected void unSubscription() { + if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) { + mCompositeSubscription.unsubscribe(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java new file mode 100644 index 0000000..b3361da --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/AuthenticateModelImpl.java @@ -0,0 +1,51 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class AuthenticateModelImpl implements IAuthenticateModel { + + private OnAuthenticateListener onAuthenticateListener; + + public AuthenticateModelImpl(OnAuthenticateListener listener) { + this.onAuthenticateListener = listener; + } + + public interface OnAuthenticateListener { + void onSuccess(PublicKeyBean key); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest() { + Observable observable = RetrofitServiceManager.authenticate(HttpConfig.BASE_IP); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (onAuthenticateListener != null) { + onAuthenticateListener.onFailure(e); + } + } + + @Override + public void onNext(PublicKeyBean key) { + if (key != null) { + onAuthenticateListener.onSuccess(key); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java new file mode 100644 index 0000000..5e0fd55 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IAuthenticateModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IAuthenticateModel { + Subscription sendRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java new file mode 100644 index 0000000..1a3681a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/ILoginActionModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface ILoginActionModel { + Subscription sendRetrofitRequest(String username, String password); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java new file mode 100644 index 0000000..74b79b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/IUserDataModel.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.model; + +import rx.Subscription; + +public interface IUserDataModel { + Subscription sendRetrofitRequest(String token); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java new file mode 100644 index 0000000..f48dbb9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/LoginActionModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class LoginActionModelImpl implements ILoginActionModel { + + private OnLoginListener loginListener; + + public LoginActionModelImpl(OnLoginListener listener) { + this.loginListener = listener; + } + + /** + * 数据回调接口 + */ + public interface OnLoginListener { + void onSuccess(LoginResultBean resultBean); + + void onFailure(Throwable throwable); + } + + + @Override + public Subscription sendRetrofitRequest(String username, String key) { + Observable observable = RetrofitServiceManager.getTokenData(HttpConfig.BASE_IP, username, key); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (loginListener != null) { + loginListener.onFailure(e); + } + } + + @Override + public void onNext(LoginResultBean resultBean) { + if (resultBean != null) { + loginListener.onSuccess(resultBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java new file mode 100644 index 0000000..d71558d --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/model/UserDataModelImpl.java @@ -0,0 +1,55 @@ +package com.casic.dcms.mvp.model; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; +import com.casic.dcms.utils.retrofit.RetrofitServiceManager; + +import rx.Observable; +import rx.Observer; +import rx.Subscription; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class UserDataModelImpl implements IUserDataModel { + + private static final String TAG = "UserDataModelImpl"; + private OnObtainUserListener listener; + + public UserDataModelImpl(OnObtainUserListener obtainUserListener) { + this.listener = obtainUserListener; + } + + /** + * 数据回调接口 + */ + public interface OnObtainUserListener { + void onSuccess(UserBean userBean); + + void onFailure(Throwable throwable); + } + + @Override + public Subscription sendRetrofitRequest(String token) { + Observable observable = RetrofitServiceManager.getUserData(HttpConfig.BASE_IP, token); + return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { + @Override + public void onCompleted() { + + } + + @Override + public void onError(Throwable e) { + if (listener != null) { + listener.onFailure(e); + } + } + + @Override + public void onNext(UserBean userBean) { + if (userBean != null) { + listener.onSuccess(userBean); + } + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java new file mode 100644 index 0000000..50a32db --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/AuthenticatePresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.AuthenticateModelImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; + +public class AuthenticatePresenterImpl extends BasePresenter implements IAuthenticatePresenter, AuthenticateModelImpl.OnAuthenticateListener { + + private IAuthenticateView view; + private AuthenticateModelImpl model; + + public AuthenticatePresenterImpl(IAuthenticateView authenticateView) { + this.view = authenticateView; + model = new AuthenticateModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest() { + view.showProgress(); + addSubscription(model.sendRetrofitRequest()); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(PublicKeyBean key) { + view.authenticateResult(key); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java new file mode 100644 index 0000000..75ff3f4 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IAuthenticatePresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IAuthenticatePresenter { + void onReadyRetrofitRequest(); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java new file mode 100644 index 0000000..0a49a43 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/ILoginPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface ILoginPresenter { + void onReadyRetrofitRequest(String username, String password); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java new file mode 100644 index 0000000..0bbae05 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/IUserDataPresenter.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.presenter; + +public interface IUserDataPresenter { + void onReadyRetrofitRequest(String token); + + void disposeRetrofitRequest(); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java new file mode 100644 index 0000000..1742de5 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/LoginPresenterImpl.java @@ -0,0 +1,38 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.LoginActionModelImpl; +import com.casic.dcms.mvp.view.ILoginView; + +public class LoginPresenterImpl extends BasePresenter implements ILoginPresenter, LoginActionModelImpl.OnLoginListener { + + private ILoginView view; + private LoginActionModelImpl actionModel; + + public LoginPresenterImpl(ILoginView loginView) { + this.view = loginView; + actionModel = new LoginActionModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String username, String key) { + addSubscription(actionModel.sendRetrofitRequest(username, key)); + } + + @Override + public void onSuccess(LoginResultBean resultBean) { + view.hideProgress(); + view.obtainLoginResult(resultBean); + } + + @Override + public void onFailure(Throwable throwable) { + view.hideProgress(); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java new file mode 100644 index 0000000..7c3a0ff --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/presenter/UserDataPresenterImpl.java @@ -0,0 +1,37 @@ +package com.casic.dcms.mvp.presenter; + +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.BasePresenter; +import com.casic.dcms.mvp.model.UserDataModelImpl; +import com.casic.dcms.mvp.view.IUserDataView; + +public class UserDataPresenterImpl extends BasePresenter implements IUserDataPresenter, UserDataModelImpl.OnObtainUserListener { + + private IUserDataView view; + private UserDataModelImpl actionModel; + + public UserDataPresenterImpl(IUserDataView userDataView) { + this.view = userDataView; + actionModel = new UserDataModelImpl(this); + } + + @Override + public void onReadyRetrofitRequest(String token) { + addSubscription(actionModel.sendRetrofitRequest(token)); + } + + @Override + public void disposeRetrofitRequest() { + unSubscription(); + } + + @Override + public void onSuccess(UserBean userBean) { + view.obtainUserData(userBean); + } + + @Override + public void onFailure(Throwable throwable) { + + } +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java new file mode 100644 index 0000000..873d0e6 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IAuthenticateView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.PublicKeyBean; + +public interface IAuthenticateView { + void showProgress(); + + void authenticateResult(PublicKeyBean result); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java new file mode 100644 index 0000000..63e6447 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/ILoginView.java @@ -0,0 +1,9 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.LoginResultBean; + +public interface ILoginView { + void hideProgress(); + + void obtainLoginResult(LoginResultBean resultBean); +} diff --git a/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java new file mode 100644 index 0000000..bcd16a9 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/mvp/view/IUserDataView.java @@ -0,0 +1,7 @@ +package com.casic.dcms.mvp.view; + +import com.casic.dcms.bean.UserBean; + +public interface IUserDataView { + void obtainUserData(UserBean userBean); +} diff --git a/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java new file mode 100644 index 0000000..2fdb879 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/CaseUploadActivity.java @@ -0,0 +1,385 @@ +package com.casic.dcms.ui; + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.media.MediaRecorder; +import android.text.TextUtils; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.GridView; +import android.widget.ImageView; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.ImageGridViewAdapter; +import com.casic.dcms.base.BaseActivity; +import com.casic.dcms.utils.FileUtils; +import com.casic.dcms.utils.GlideLoadEngine; +import com.casic.dcms.utils.LocationHelper; +import com.casic.dcms.utils.callback.ILocationListener; +import com.google.gson.Gson; +import com.luck.picture.lib.PictureSelector; +import com.luck.picture.lib.config.PictureConfig; +import com.luck.picture.lib.config.PictureMimeType; +import com.luck.picture.lib.entity.LocalMedia; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; +import com.qmuiteam.qmui.widget.dialog.QMUIDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.OnClick; + +public class CaseUploadActivity extends BaseActivity + implements View.OnClickListener, View.OnTouchListener { + + private static final String TAG = "CaseUploadActivity"; + + @BindView(R.id.caseTopLayout) + QMUITopBarLayout caseTopLayout; + + @BindView(R.id.communityNameView) + EditText communityNameView; + @BindView(R.id.longitudeView) + EditText longitudeView; + @BindView(R.id.latitudeView) + EditText latitudeView; + @BindView(R.id.locationMapView) + ImageView locationMapView; + @BindView(R.id.caseDetailEditView) + EditText caseDetailEditView; + @BindView(R.id.voiceView) + ImageView voiceView; + @BindView(R.id.addImageView) + ImageView addImageView; + @BindView(R.id.selectedResultView) + GridView selectedResultView; + @BindView(R.id.submitButton) + QMUIRoundButton submitButton; + + private MediaRecorder mediaRecorder; + private File outputFile; + private List mediaList = new ArrayList<>();//拍照或者视频数据集 + + @Override + public int initLayoutView() { + return R.layout.activity_case_upload; + } + + @Override + protected void setupTopBarLayout() { + caseTopLayout.setTitle("案卷上报").setTextColor(ContextCompat.getColor(this, R.color.black)); + caseTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + caseTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + LocationHelper.obtainCurrentLocation(this, new ILocationListener() { + @Override + public void onLocationGet(Location location) { + updateLocation(location); + } + }); + initMediaRecorder(); + } + + private void updateLocation(Location location) { + if (location != null) { + double longitude = location.getLongitude(); + longitudeView.setText(String.valueOf(longitude)); + double latitude = location.getLatitude(); + latitudeView.setText(String.valueOf(latitude)); + Geocoder geoCoder = new Geocoder(this, Locale.CHINESE); + StringBuffer buffer = new StringBuffer(); + try { + Address address = geoCoder.getFromLocation(latitude, longitude, 1).get(0); +// Log.d(TAG, "getLocality: " + address.getLocality()); +// Log.d(TAG, "getSubLocality: " + address.getSubLocality()); +// Log.d(TAG, "getAdminArea: " + address.getAdminArea()); +// Log.d(TAG, "getSubAdminArea: " + address.getSubAdminArea()); +// Log.d(TAG, "getThoroughfare: " + address.getThoroughfare()); +// Log.d(TAG, "getSubThoroughfare: " + address.getSubThoroughfare()); + buffer.append(address.getSubLocality()) + .append(address.getSubAdminArea()) + .append(address.getThoroughfare()) + .append(address.getSubThoroughfare()); + } catch (IOException e) { + buffer.append("解析详细地址失败"); + e.printStackTrace(); + } + communityNameView.setText(buffer); + +// CameraPosition cameraPosition = new CameraPosition(new LatLng(latitude, longitude), 15, 0, 30); +// CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition); +// aMap.moveCamera(cameraUpdate); +// drawMarkers(latitude, longitude); + } + } + + /** + * 初始化MediaRecorder + */ + private void initMediaRecorder() { + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//麦克风 + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioSamplingRate(44100); + //设置编码 + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setAudioEncodingBitRate(96000); + outputFile = FileUtils.getOutputAudioFile(); + mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); + try { + mediaRecorder.prepare(); + } catch (IllegalStateException | IOException e) { + Log.d(TAG, "initMediaRecorder: " + e); + releaseMediaRecorder(); + } + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void initEvent() { + //地图图标点击事件 + locationMapView.setOnClickListener(this); + //录音按钮点击事件 + voiceView.setOnTouchListener(this); + //添加图片或者视频按钮点击事件 + addImageView.setOnClickListener(this); + //提交按钮点击事件 + submitButton.setChangeAlphaWhenPress(true); + submitButton.setOnClickListener(this); + } + + @OnClick({R.id.locationMapView, R.id.addImageView, R.id.submitButton}) + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.locationMapView: + startActivity(new Intent(this, MapActivity.class)); + break; + case R.id.addImageView: + new QMUIDialog.MenuDialogBuilder(this) + .addItem("相册中选取", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //选图 + selectPicture(); + } + }) + .addItem("相机拍照", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍照 + takePicture(); + } + }) + .addItem("相机拍视频", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + //拍视频 + takeVideo(); + } + }) + .setCanceledOnTouchOutside(false) + .create().show(); + break; + case R.id.submitButton: + + break; + default: + break; + } + } + + private void selectPicture() { + PictureSelector.create(this) + .openGallery(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(3) + .forResult(PictureConfig.CHOOSE_REQUEST); + } + + private void takePicture() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofImage()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + private void takeVideo() { + PictureSelector.create(this) + .openCamera(PictureMimeType.ofVideo()) + .imageEngine(GlideLoadEngine.createGlideEngine()) + .maxSelectNum(1) + .forResult(PictureConfig.REQUEST_CAMERA); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case PictureConfig.CHOOSE_REQUEST: + List selectList = PictureSelector.obtainMultipleResult(data); + Log.d(TAG, "onActivityResult: " + new Gson().toJson(selectList)); + if (selectList != null && selectList.size() > 0) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + ImageGridViewAdapter imageGridViewAdapter = new ImageGridViewAdapter(this, selectList); + selectedResultView.setAdapter(imageGridViewAdapter); + //九宫格点击事件 + selectedResultView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + //查看大图 + showBigImage(selectList.get(position)); + } + }); + //删除按钮点击事件 + imageGridViewAdapter.setOnDeleteClickListener(new ImageGridViewAdapter.OnDeleteItemClickListener() { + @Override + public void onClick(int position) { + selectList.remove(position); + imageGridViewAdapter.notifyDataSetChanged(); + if (selectList.size() == 0) { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + } + }); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + case PictureConfig.REQUEST_CAMERA: + LocalMedia localMedia = PictureSelector.obtainMultipleResult(data).get(0); + mediaList.add(localMedia); + //重排序 + reOrderList(mediaList); + //TODO 未完成 需要判断是照片还是视频 + + + if (mediaList.size() == 3) { + addImageView.setVisibility(View.GONE); + selectedResultView.setVisibility(View.VISIBLE); + + + Log.d(TAG, "onActivityResult: " + new Gson().toJson(localMedia)); + } else { + addImageView.setVisibility(View.VISIBLE); + selectedResultView.setVisibility(View.GONE); + } + break; + default: + break; + } + } + } + + private void reOrderList(List list) { + for (int i = 0; i < list.size(); i++) { + LocalMedia localMedia = list.get(i); + if (localMedia.getMimeType().equals("video/mp4")) { + mediaList.add(0, localMedia);//视频必须放在第一个 + } else { + mediaList.add(localMedia); + } + } + } + + private void showBigImage(LocalMedia localMedia) { + + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + //按下动画 + voiceView.animate().scaleX(0.75f).scaleY(0.75f).setDuration(100).start(); + /** + * 录音 + * 点击切换时,需判断输入框内是否有文字,如有,需确认是否切换。若切换则,已输入的文字无法保存 + * */ + String caseDetail = caseDetailEditView.getText().toString().trim(); + if (TextUtils.isEmpty(caseDetail)) { + //可以录音 + startRecordedVoice(); + } else { + //提醒用户是否确认要切换录音 + new QMUIDialog.MessageDialogBuilder(this) + .setTitle("提示") + .setMessage("输入框内是否有文字,是否确认切换?") + .setCanceledOnTouchOutside(false) + .addAction("取消", (dialog, index) -> dialog.dismiss()) + .addAction("确认", (dialog, index) -> { + dialog.dismiss(); + caseDetailEditView.setText(""); + //切换录音 + startRecordedVoice(); + }).create().show(); + } + break; + case MotionEvent.ACTION_UP: + //松开动画 + voiceView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start(); + //停止录音 + releaseMediaRecorder(); + break; + } + return true; + } + + /** + * 录音,保存文件 + */ + private void startRecordedVoice() { + Log.d(TAG, "startRecordedVoice: 开始录音"); + if (mediaRecorder != null) { + mediaRecorder.start(); + } + } + + private void releaseMediaRecorder() { + Log.d(TAG, "releaseMediaRecorder: 录音已停止"); + if (mediaRecorder != null) { + mediaRecorder.reset(); + mediaRecorder.release(); + mediaRecorder = null; + } + //显示录音文件路径 + if (outputFile.exists()) { + caseDetailEditView.setText(outputFile.getAbsolutePath()); + } else { + caseDetailEditView.setText("录音保存失败"); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/LoginActivity.java b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java new file mode 100644 index 0000000..433c40f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/LoginActivity.java @@ -0,0 +1,168 @@ +package com.casic.dcms.ui; + + +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Toast; + +import com.casic.dcms.R; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.mvp.presenter.AuthenticatePresenterImpl; +import com.casic.dcms.mvp.presenter.LoginPresenterImpl; +import com.casic.dcms.mvp.view.IAuthenticateView; +import com.casic.dcms.mvp.view.ILoginView; +import com.casic.dcms.utils.RSAUtils; +import com.casic.dcms.utils.SaveKeyValues; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import com.qmuiteam.qmui.widget.dialog.QMUITipDialog; +import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton; + +import java.security.PublicKey; + +import butterknife.BindView; +import butterknife.OnClick; + +public class LoginActivity extends DoubleClickExitActivity + implements View.OnClickListener, IAuthenticateView, ILoginView { + + private static final String TAG = "LoginActivity"; + + @BindView(R.id.userNameView) + EditText userNameView; + @BindView(R.id.userPasswordView) + EditText userPasswordView; + @BindView(R.id.loginButton) + QMUIRoundButton loginButton; + @BindView(R.id.rememberPasswordView) + CheckBox rememberPasswordView; + @BindView(R.id.autoLoginView) + CheckBox autoLoginView; + + private QMUITipDialog loadingDialog; + private AuthenticatePresenterImpl authenticatePresenter; + private LoginPresenterImpl loginPresenter; + private String userName; + private String userPassword; + + @Override + public int initLayoutView() { + return R.layout.activity_login; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + //设置状态栏黑色字体图标 + QMUIStatusBarHelper.setStatusBarLightMode(this); + + String userName = (String) SaveKeyValues.getValue("userName", ""); + String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); + if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { + userNameView.setText(userName); + userPasswordView.setText(userPassword); + } + loadingDialog = new QMUITipDialog.Builder(this) + .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING) + .setTipWord("登陆中,请稍后") + .create(); + } + + @Override + public void initEvent() { + loginButton.setChangeAlphaWhenPress(true); + authenticatePresenter = new AuthenticatePresenterImpl(this); + loginPresenter = new LoginPresenterImpl(this); + } + + @OnClick(R.id.loginButton) + @Override + public void onClick(View v) { + userName = userNameView.getText().toString(); + userPassword = userPasswordView.getText().toString(); + if (rememberPasswordView.isChecked()) { + SaveKeyValues.putValue("userName", userName); + SaveKeyValues.putValue("userPassword", userPassword); + } + //验证公钥 + authenticatePresenter.onReadyRetrofitRequest(); + } + + @Override + protected void onResume() { + super.onResume(); + //自动登录 +// if (autoLoginView.isChecked()) { +// String userName = (String) SaveKeyValues.getValue("userName", ""); +// String userPassword = (String) SaveKeyValues.getValue("userPassword", ""); +// if (!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPassword)) { +// loginPresenter.onReadyRetrofitRequest(userName, userPassword); +// } else { +// Toast.makeText(this, "自动登录失败,请检查", Toast.LENGTH_SHORT).show(); +// } +// } + } + + @Override + public void showProgress() { + loadingDialog.show(); + } + + @Override + public void authenticateResult(PublicKeyBean result) { + if (result.isSuccess()) { + PublicKey publicKey = RSAUtils.keyStrToPublicKey(result.getData().getPublicKey()); + if (TextUtils.isEmpty(userName)) { + Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show(); + return; + } + if (TextUtils.isEmpty(userPassword)) { + Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show(); + return; + } + String dataByPublicKey = RSAUtils.encryptDataByPublicKey(userPassword.getBytes(), publicKey); + Log.d(TAG, "authenticateResult: 验证成功,开始登录"); + //登录并获取Token,POST请求 + loginPresenter.onReadyRetrofitRequest(userName, dataByPublicKey); + } + } + + @Override + public void obtainLoginResult(LoginResultBean result) { + String token = result.getData().getToken(); + if (!TextUtils.isEmpty(token)) { + //获取用户信息 + Log.d(TAG, "obtainLoginResult: 获取Token成功"); + TokenHelper.saveToken(token); + //验证成功登录 + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + } + + @Override + public void hideProgress() { + loadingDialog.hide(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (authenticatePresenter != null) { + authenticatePresenter.disposeRetrofitRequest(); + } + if (loginPresenter != null) { + loginPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MainActivity.java b/app/src/main/java/com/casic/dcms/ui/MainActivity.java new file mode 100644 index 0000000..88a2c46 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MainActivity.java @@ -0,0 +1,104 @@ +package com.casic.dcms.ui; + +import android.util.Log; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.viewpager.widget.ViewPager; + +import com.casic.dcms.R; +import com.casic.dcms.adapter.MainPageAdapter; +import com.casic.dcms.base.DoubleClickExitActivity; +import com.casic.dcms.ui.fragment.DashBoardPageFragment; +import com.casic.dcms.ui.fragment.HomePageFragment; +import com.casic.dcms.ui.fragment.MinePageFragment; +import com.casic.dcms.ui.fragment.PhonePageFragment; +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; + +public class MainActivity extends DoubleClickExitActivity { + + private static final String TAG = "MainActivity"; + + @BindView(R.id.mainViewPager) + ViewPager mainViewPager; + @BindView(R.id.bottomNavigation) + BottomNavigationView bottomNavigation; + private MenuItem menuItem; + private List pageList; + + @Override + public int initLayoutView() { + return R.layout.activity_main; + } + + @Override + protected void setupTopBarLayout() { + //TODO 此页面无需实现 + } + + @Override + public void initData() { + pageList = new ArrayList<>(); + pageList.add(new HomePageFragment()); + pageList.add(new PhonePageFragment()); + pageList.add(new DashBoardPageFragment()); + pageList.add(new MinePageFragment()); + } + + @Override + public void initEvent() { + bottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.navigation_home: + mainViewPager.setCurrentItem(0); + break; + case R.id.navigation_phone: + mainViewPager.setCurrentItem(1); + break; + case R.id.navigation_dashboard: + mainViewPager.setCurrentItem(2); + break; + case R.id.navigation_mine: + mainViewPager.setCurrentItem(3); + break; + default: + Log.e(TAG, "onNavigationItemSelected: ", new IndexOutOfBoundsException()); + break; + } + return false; + } + }); + mainViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (menuItem != null) { + menuItem.setChecked(false); + } else { + bottomNavigation.getMenu().getItem(0).setChecked(false); + } + menuItem = bottomNavigation.getMenu().getItem(position); + menuItem.setChecked(true); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + MainPageAdapter mainPageAdapter = new MainPageAdapter(getSupportFragmentManager(), pageList); + mainViewPager.setAdapter(mainPageAdapter); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/MapActivity.java b/app/src/main/java/com/casic/dcms/ui/MapActivity.java new file mode 100644 index 0000000..40a3542 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/MapActivity.java @@ -0,0 +1,163 @@ +package com.casic.dcms.ui; + +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseActivity; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolDragListener; +import com.mapbox.mapboxsdk.plugins.annotation.OnSymbolLongClickListener; +import com.mapbox.mapboxsdk.plugins.annotation.Symbol; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolManager; +import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; +import com.qmuiteam.qmui.widget.QMUITopBarLayout; + +import org.jetbrains.annotations.NotNull; + +import butterknife.BindView; + +import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_VIEWPORT; + +public class MapActivity extends BaseActivity { + + private static final String TAG = "MapActivity"; + @BindView(R.id.mapTopLayout) + QMUITopBarLayout mapTopLayout; + @BindView(R.id.mapBoxView) + MapView mapBoxView; + + @Override + public int initLayoutView() { + return R.layout.activity_map; + } + + @Override + protected void setupTopBarLayout() { + mapTopLayout.setTitle("选择点位").setTextColor(ContextCompat.getColor(this, R.color.black)); + mapTopLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.lightGray)); + mapTopLayout.addLeftImageButton(R.drawable.ic_left_black, 0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + @Override + public void initData() { + mapBoxView.getMapAsync(new OnMapReadyCallback() { + @Override + public void onMapReady(@NonNull MapboxMap mapboxMap) { +// mapboxMap.setStyle(Style.MAPBOX_STREETS);//基本地图 +// mapboxMap.setStyle(Style.SATELLITE);//卫星图 +// mapboxMap.setStyle(Style.TRAFFIC_DAY);//白天交通路线图 +// mapboxMap.setStyle(Style.SATELLITE_STREETS);//卫星街道图 + mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + //基本地图上面自定义地图 + SymbolManager symbolManager = new SymbolManager(mapBoxView, mapboxMap, style); + symbolManager.addClickListener(new OnSymbolClickListener() { + //点击事件 + @Override + public boolean onAnnotationClick(Symbol symbol) { + Log.d(TAG, "onAnnotationClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addLongClickListener(new OnSymbolLongClickListener() { + //长按事件 + @Override + public boolean onAnnotationLongClick(Symbol symbol) { + Log.d(TAG, "onAnnotationLongClick: " + symbol.getLatLng()); + return false; + } + }); + symbolManager.addDragListener(new OnSymbolDragListener() { + //拖拽事件 + @Override + public void onAnnotationDragStarted(Symbol annotation) { + Log.d(TAG, "onAnnotationDragStarted: 开始"); + } + + @Override + public void onAnnotationDrag(Symbol annotation) { + Log.d(TAG, "onAnnotationDrag: 拖拽中"); + } + + @Override + public void onAnnotationDragFinished(Symbol annotation) { + Log.d(TAG, "onAnnotationDragFinished: 结束"); + } + }); + symbolManager.setIconAllowOverlap(true); + symbolManager.setIconIgnorePlacement(true); + symbolManager.setIconTranslate(new Float[]{-4f, 5f}); + symbolManager.setIconRotationAlignment(ICON_ROTATION_ALIGNMENT_VIEWPORT); + Symbol symbol = symbolManager.create(new SymbolOptions() + .withLatLng(new LatLng(39.91435564744717, 116.26274417954977)) + .withIconImage("") + .withIconSize(2.0f)); + } + }); + } + }); + } + + @Override + public void initEvent() { + + } + + @Override + protected void onStart() { + super.onStart(); + mapBoxView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapBoxView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapBoxView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapBoxView.onStop(); + } + + @Override + protected void onSaveInstanceState(@NotNull Bundle outState) { + super.onSaveInstanceState(outState); + mapBoxView.onSaveInstanceState(outState); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapBoxView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapBoxView.onDestroy(); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java new file mode 100644 index 0000000..07de568 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/PermissionActivity.java @@ -0,0 +1,58 @@ +package com.casic.dcms.ui; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.casic.dcms.utils.Constant; + +import java.util.List; + +import pub.devrel.easypermissions.EasyPermissions; + + +public class PermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { + + private static final String TAG = "PermissionActivity"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //判断是否有权限,如果版本大于5.1才需要判断(即6.0以上),其他则不需要判断。 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (EasyPermissions.hasPermissions(this, Constant.USER_PERMISSIONS)) { + startLoginActivity(); + } else { + EasyPermissions.requestPermissions(this, "需要获取相关权限", Constant.PERMISSIONS_CODE, Constant.USER_PERMISSIONS); + } + } else { + startLoginActivity(); + } + } + + private void startLoginActivity() { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); + } + + @Override + public void onPermissionsGranted(int requestCode, @NonNull List perms) { + startLoginActivity(); + } + + @Override + public void onPermissionsDenied(int requestCode, @NonNull List perms) { + Log.e(TAG, "onPermissionsDenied: " + perms); + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java new file mode 100644 index 0000000..a1e68ba --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/DashBoardPageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class DashBoardPageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_dashboard; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java new file mode 100644 index 0000000..6b8aa5f --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/HomePageFragment.java @@ -0,0 +1,140 @@ +package com.casic.dcms.ui.fragment; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.casic.dcms.R; +import com.casic.dcms.adapter.HomeRecycleAdapter; +import com.casic.dcms.base.BaseFragment; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.mvp.presenter.UserDataPresenterImpl; +import com.casic.dcms.mvp.view.IUserDataView; +import com.casic.dcms.ui.CaseUploadActivity; +import com.casic.dcms.utils.TokenHelper; +import com.qmuiteam.qmui.widget.QMUIRadiusImageView; + +import butterknife.BindView; + +/** + * 此页面后期可能需要添加滑动吸顶效果 + */ +public class HomePageFragment extends BaseFragment implements IUserDataView { + + private static final String TAG = "HomePageFragment"; + @BindView(R.id.userIconView) + QMUIRadiusImageView userIconView; + @BindView(R.id.userNameView) + TextView userNameView; + @BindView(R.id.userDeptView) + TextView userDeptView; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + private Context context; + private UserDataPresenterImpl userDataPresenter; + + @Override + protected int initLayoutView() { + return R.layout.fragment_home; + } + + @Override + protected void initData() { + context = getContext(); + userDataPresenter = new UserDataPresenterImpl(this); + + String token = TokenHelper.getToken(); + if (TextUtils.isEmpty(token)) { + Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show(); + return; + } + userDataPresenter.onReadyRetrofitRequest(token); + } + + @Override + protected void initEvent() { + HomeRecycleAdapter adapter = new HomeRecycleAdapter(context); + homeRecyclerView.setLayoutManager(new GridLayoutManager(context, 3)); + homeRecyclerView.setAdapter(adapter); + adapter.setOnGridItemClickListener(new HomeRecycleAdapter.OnGridItemClickListener() { + @Override + public void onClick(int position) { + Intent intent = new Intent(); + switch (position) { + case 0: + intent.setClass(context, CaseUploadActivity.class); + startActivity(intent); + break; + case 1: + + break; + case 2: + + break; + case 3: + + break; + case 4: + + case 5: + + break; + case 6: + + break; + case 7: + + break; + case 8: + + break; + case 9: + + break; + case 10: + + break; + case 11: + + break; + default: + break; + } + } + }); + } + + @SuppressLint("SetTextI18n") + @Override + public void obtainUserData(UserBean userBean) { +// Log.d(TAG, "obtainUserData: " + new Gson().toJson(userBean)); + if (userBean.isSuccess()) { + //QMUIRadiusImageView无法动态设置圆形头像,借助Glide实现圆形头像 + Glide.with(this).load(R.mipmap.app_logo).apply(RequestOptions.circleCropTransform()).into(userIconView); + + UserBean.DataBean data = userBean.getData(); + userNameView.setText(data.getName()); + userDeptView.setText(data.getDeptName() + data.getRoleNames()); + } else { + Toast.makeText(context, "", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (userDataPresenter != null) { + userDataPresenter.disposeRetrofitRequest(); + } + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java new file mode 100644 index 0000000..f698e72 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/MinePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class MinePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_mine; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java new file mode 100644 index 0000000..f07526a --- /dev/null +++ b/app/src/main/java/com/casic/dcms/ui/fragment/PhonePageFragment.java @@ -0,0 +1,21 @@ +package com.casic.dcms.ui.fragment; + +import com.casic.dcms.R; +import com.casic.dcms.base.BaseFragment; + +public class PhonePageFragment extends BaseFragment { + @Override + protected int initLayoutView() { + return R.layout.fragment_phone; + } + + @Override + protected void initData() { + + } + + @Override + protected void initEvent() { + + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/Constant.java b/app/src/main/java/com/casic/dcms/utils/Constant.java new file mode 100644 index 0000000..49c80b7 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/Constant.java @@ -0,0 +1,34 @@ +package com.casic.dcms.utils; + +import android.Manifest; + +import com.casic.dcms.R; + +import java.util.Arrays; +import java.util.List; + +public class Constant { + public static final List ICONS = Arrays.asList( + R.mipmap.ajsb, R.mipmap.kssb, R.mipmap.sbsb, + R.mipmap.ajhs, R.mipmap.ajhc, R.mipmap.ajcl, + R.mipmap.jjyj, R.mipmap.csdb, R.mipmap.tjfx, + R.mipmap.zgry, R.mipmap.ajcx, R.mipmap.dtck); + + public static final List ITEMS = Arrays.asList( + "案卷上报", "快速上报", "三包上报", + "案卷核实", "案卷核查", "案卷处理", + "紧急要件", "超时督办", "统计分析", + "在岗人员", "案卷查询", "地图查看"); + + public static final String[] USER_PERMISSIONS = { + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.CAMERA, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.RECORD_AUDIO}; + + public static final int SELECT_PICTURE_CODE = 9001; + + public static final int PERMISSIONS_CODE = 999; +} diff --git a/app/src/main/java/com/casic/dcms/utils/FileUtils.java b/app/src/main/java/com/casic/dcms/utils/FileUtils.java new file mode 100644 index 0000000..7e9c161 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/FileUtils.java @@ -0,0 +1,28 @@ +package com.casic.dcms.utils; + +import android.os.Environment; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class FileUtils { + public static File getOutputAudioFile() { + File audioDir = new File(Environment.getExternalStorageDirectory(), "AudioFile"); + if (!audioDir.exists()) { + audioDir.mkdir(); + } + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); + File audioFile = new File(audioDir + File.separator + "AUD_" + timeStamp + ".m4a"); + if (!audioFile.exists()) { + try { + audioFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return audioFile; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java new file mode 100644 index 0000000..df2500b --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/GlideLoadEngine.java @@ -0,0 +1,89 @@ +package com.casic.dcms.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; +import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.BitmapImageViewTarget; +import com.casic.dcms.R; +import com.luck.picture.lib.engine.ImageEngine; +import com.luck.picture.lib.listener.OnImageCompleteCallback; +import com.luck.picture.lib.widget.longimage.SubsamplingScaleImageView; + +/** + * @Author: Pengxh + * @Time: 2021/4/7 15:54 + * @Emain: 290677893@qq.com + **/ +public class GlideLoadEngine implements ImageEngine { + + private GlideLoadEngine() { + + } + + private static GlideLoadEngine instance; + + public static GlideLoadEngine createGlideEngine() { + if (null == instance) { + synchronized (GlideLoadEngine.class) { + if (null == instance) { + instance = new GlideLoadEngine(); + } + } + } + return instance; + } + + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).load(url).into(imageView); + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView, OnImageCompleteCallback callback) { + + } + + @Override + public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, SubsamplingScaleImageView longImageView) { + + } + + @Override + public void loadFolderImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .asBitmap() + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(new BitmapImageViewTarget(imageView) { + @Override + protected void setResource(Bitmap resource) { + RoundedBitmapDrawable circularBitmapDrawable = + RoundedBitmapDrawableFactory. + create(context.getResources(), resource); + circularBitmapDrawable.setCornerRadius(8); + imageView.setImageDrawable(circularBitmapDrawable); + } + }); + } + + @Override + public void loadAsGifImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context).asGif().load(url).into(imageView); + } + + @Override + public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) { + Glide.with(context) + .load(url) + .apply(new RequestOptions().placeholder(R.drawable.picture_image_placeholder)) + .into(imageView); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpConfig.java b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java new file mode 100644 index 0000000..bd3eb2e --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpConfig.java @@ -0,0 +1,8 @@ +package com.casic.dcms.utils; + +public class HttpConfig { + public static final String BASE_IP = "http://111.198.10.15:11409"; + public static final long HTTP_TIMEOUT = 30L; + public static final String HTTP_TOKEN_KET = ""; + public static final int REQUEST_TOKEN_INVALID = 0; +} diff --git a/app/src/main/java/com/casic/dcms/utils/HttpHelper.java b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java new file mode 100644 index 0000000..0edc9de --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/HttpHelper.java @@ -0,0 +1,64 @@ +package com.casic.dcms.utils; + +import android.util.Log; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import rx.Observable; +import rx.Subscriber; +import rx.android.schedulers.AndroidSchedulers; +import rx.schedulers.Schedulers; + +public class HttpHelper { + private static final String TAG = "HttpHelper"; + + public static void doHttpRequest(String token) { + Observable.create((Observable.OnSubscribe) subscriber -> + new OkHttpClient().newCall(new Request.Builder() + .addHeader("token", token) + .url("http://111.198.10.15:11409/user/info/") + .get() + .build()) + .enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + subscriber.onError(e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + subscriber.onNext(response); + } + })).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber() { + @Override + public void onError(Throwable e) { + Log.d(TAG, "onError: " + e); + } + + @Override + public void onNext(Response response) { + if (response == null) { + Log.e(TAG, "请求出错: ", new NullPointerException()); + return; + } + try { + Log.d(TAG, "onNext: " + response.body().string()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onCompleted() { + Log.d(TAG, "onCompleted: 请求完成"); + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/LocationHelper.java b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java new file mode 100644 index 0000000..d21b9bd --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/LocationHelper.java @@ -0,0 +1,53 @@ +package com.casic.dcms.utils; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; + +import androidx.core.app.ActivityCompat; + +import com.casic.dcms.utils.callback.ILocationListener; + +import org.jetbrains.annotations.NotNull; + +public class LocationHelper { + /** + * 获取当前定位 + */ + public static void obtainCurrentLocation(Context context, ILocationListener listener) { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED + && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + return; + } + LocationManager mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + //首次定位 + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + listener.onLocationGet(location); + //位置变化时更新位置 + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 10, new LocationListener() { + @Override + public void onLocationChanged(@NotNull Location location) { + listener.onLocationGet(location); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(@NotNull String provider) { + + } + + @Override + public void onProviderDisabled(@NotNull String provider) { + + } + }); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/RSAUtils.java b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java new file mode 100644 index 0000000..a35be19 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/RSAUtils.java @@ -0,0 +1,69 @@ +package com.casic.dcms.utils; + +import android.util.Base64; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +/** + * Created by W530 on 2019/9/26. + */ + +public class RSAUtils { + //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding" + private static String sTransform = "RSA/None/PKCS1Padding"; + //进行Base64转码时的flag设置,默认为Base64.DEFAULT + private static int sBase64Mode = Base64.DEFAULT; + + //初始化方法,设置参数 + public static void init(String transform, int base64Mode) { + sTransform = transform; + sBase64Mode = base64Mode; + } + + + private static byte[] processData(byte[] srcData, Key key, int mode) { + //用来保存处理结果 + byte[] resultBytes = null; + try { + //获取Cipher实例 + Cipher cipher = Cipher.getInstance(sTransform); + //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥 + cipher.init(mode, key); + //处理数据 + resultBytes = cipher.doFinal(srcData); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { + e.printStackTrace(); + } + return resultBytes; + } + + public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey) { + byte[] resultBytes = processData(srcData, publicKey, Cipher.ENCRYPT_MODE); + return Base64.encodeToString(resultBytes, sBase64Mode); + } + + public static PublicKey keyStrToPublicKey(String publicKeyStr) { + PublicKey publicKey = null; + byte[] keyBytes = Base64.decode(publicKeyStr, sBase64Mode); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + try { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + publicKey = keyFactory.generatePublic(keySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return publicKey; + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java new file mode 100644 index 0000000..5781791 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/SaveKeyValues.java @@ -0,0 +1,92 @@ +package com.casic.dcms.utils; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +public class SaveKeyValues { + private static final String TAG = "SaveKeyValues"; + + @SuppressLint({"StaticFieldLeak"}) + private static Context context; + private static SharedPreferences sharedPreferences; + private static SharedPreferences.Editor editor; + private static String fileName; + + public static void initSharedPreferences(Context mContext) { + context = mContext.getApplicationContext(); + String packageName = context.getPackageName(); + //获取到的包名带有“.”方便命名,取最后一个作为sp文件名,例如:com.casic.dcms + String[] split = packageName.split("\\.");//先转义.之后才能分割 + int length = split.length; + fileName = split[length - 1]; + Log.d(TAG, fileName); + } + + /** + * 存储 + */ + public static void putValue(String key, Object object) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + if (object instanceof String) { + editor.putString(key, (String) object); + } else if (object instanceof Integer) { + editor.putInt(key, (Integer) object); + } else if (object instanceof Boolean) { + editor.putBoolean(key, (Boolean) object); + } else if (object instanceof Float) { + editor.putFloat(key, (Float) object); + } else if (object instanceof Long) { + editor.putLong(key, (Long) object); + } else { + editor.putString(key, object.toString()); + } + editor.apply(); + } + + /** + * 获取保存的数据 + */ + public static Object getValue(String key, Object defaultObject) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + if (defaultObject instanceof String) { + return sharedPreferences.getString(key, (String) defaultObject); + } else if (defaultObject instanceof Integer) { + return sharedPreferences.getInt(key, (Integer) defaultObject); + } else if (defaultObject instanceof Boolean) { + return sharedPreferences.getBoolean(key, (Boolean) defaultObject); + } else if (defaultObject instanceof Float) { + return sharedPreferences.getFloat(key, (Float) defaultObject); + } else if (defaultObject instanceof Long) { + return sharedPreferences.getLong(key, (Long) defaultObject); + } else { + return sharedPreferences.getString(key, null); + } + } + + /** + * 移除某个key值已经对应的值 + */ + public static void removeKey(String key) { + editor.remove(key); + editor.commit(); + } + + /** + * 清除所有数据 + */ + public static void clearAll() { + editor.clear(); + editor.commit(); + } + + /** + * 查询某个key是否存在 + */ + public static boolean containsKey(String key) { + sharedPreferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + return sharedPreferences.contains(key); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/StringHelper.java b/app/src/main/java/com/casic/dcms/utils/StringHelper.java new file mode 100644 index 0000000..1781080 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/StringHelper.java @@ -0,0 +1,5 @@ +package com.casic.dcms.utils; + +public class StringHelper { + +} diff --git a/app/src/main/java/com/casic/dcms/utils/TokenHelper.java b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java new file mode 100644 index 0000000..a02a103 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/TokenHelper.java @@ -0,0 +1,12 @@ +package com.casic.dcms.utils; + +public class TokenHelper { + + public static void saveToken(String token) { + SaveKeyValues.putValue("token", token); + } + + public static String getToken() { + return (String) SaveKeyValues.getValue("token", ""); + } +} diff --git a/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java new file mode 100644 index 0000000..2c61981 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/callback/ILocationListener.java @@ -0,0 +1,7 @@ +package com.casic.dcms.utils.callback; + +import android.location.Location; + +public interface ILocationListener { + void onLocationGet(Location location); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java new file mode 100644 index 0000000..157c941 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitService.java @@ -0,0 +1,37 @@ +package com.casic.dcms.utils.retrofit; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; + +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.POST; +import rx.Observable; + +public interface RetrofitService { + + /** + * PublicKey校验 + */ + @GET("/config/baseConfig") + Observable getPublicKey(); + + /** + * 登录并获取Token + */ + @FormUrlEncoded + @POST("/user/appLogin") + Observable login(@Field("username") String username, + @Field("password") String password); + + /** + * 获取用户信息 + *

+ * token添加到Header + */ + @GET("/user/info") + Observable getUser(@Header("token") String token); +} diff --git a/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java new file mode 100644 index 0000000..7bf9982 --- /dev/null +++ b/app/src/main/java/com/casic/dcms/utils/retrofit/RetrofitServiceManager.java @@ -0,0 +1,75 @@ +package com.casic.dcms.utils.retrofit; + +import android.util.Log; + +import com.casic.dcms.bean.LoginResultBean; +import com.casic.dcms.bean.PublicKeyBean; +import com.casic.dcms.bean.UserBean; +import com.casic.dcms.utils.HttpConfig; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; +import rx.Observable; + +public class RetrofitServiceManager { + private static final String TAG = "RetrofitServiceManager"; + + private static Retrofit createRetrofit(String baseUrl) { + return new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create())//Gson转换器 + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .client(createOKHttpClient())//log拦截器 + .build(); + } + + private static OkHttpClient createOKHttpClient() { + //日志显示级别 + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + public void log(@NotNull String message) { + Log.d(TAG, "log: " + message); + } + }); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .readTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .connectTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(HttpConfig.HTTP_TIMEOUT, TimeUnit.SECONDS); + return builder.addInterceptor(interceptor).build(); + } + + /** + * 验证PublicKey + */ + public static Observable authenticate(String baseUrl) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getPublicKey(); + } + + /** + * 登录并获取Token + */ + public static Observable getTokenData(String baseUrl, String username, String key) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.login(username, key); + } + + /** + * 获取用户信息 + */ + public static Observable getUserData(String baseUrl, String token) { + Retrofit retrofit = createRetrofit(baseUrl); + RetrofitService service = retrofit.create(RetrofitService.class); + return service.getUser(token); + } +} diff --git a/app/src/main/res/drawable/bg_enter_bottom.png b/app/src/main/res/drawable/bg_enter_bottom.png new file mode 100644 index 0000000..6519fa0 --- /dev/null +++ b/app/src/main/res/drawable/bg_enter_bottom.png Binary files differ diff --git a/app/src/main/res/drawable/bg_layout.xml b/app/src/main/res/drawable/bg_layout.xml new file mode 100644 index 0000000..ff02e0d --- /dev/null +++ b/app/src/main/res/drawable/bg_layout.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_text_color.xml b/app/src/main/res/drawable/bottom_text_color.xml new file mode 100644 index 0000000..c5cbeda --- /dev/null +++ b/app/src/main/res/drawable/bottom_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_black.xml b/app/src/main/res/drawable/ic_add_black.xml new file mode 100644 index 0000000..5697f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white.xml b/app/src/main/res/drawable/ic_add_white.xml new file mode 100644 index 0000000..4a2aeb3 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black.xml b/app/src/main/res/drawable/ic_delete_black.xml new file mode 100644 index 0000000..482b166 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white.xml b/app/src/main/res/drawable/ic_delete_white.xml new file mode 100644 index 0000000..40313ad --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_left_black.xml b/app/src/main/res/drawable/ic_left_black.xml new file mode 100644 index 0000000..8135d7f --- /dev/null +++ b/app/src/main/res/drawable/ic_left_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_map.xml b/app/src/main/res/drawable/ic_map.xml new file mode 100644 index 0000000..e0e5132 --- /dev/null +++ b/app/src/main/res/drawable/ic_map.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_right.xml b/app/src/main/res/drawable/ic_right.xml new file mode 100644 index 0000000..bf3098b --- /dev/null +++ b/app/src/main/res/drawable/ic_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_voice.xml b/app/src/main/res/drawable/ic_voice.xml new file mode 100644 index 0000000..563ae21 --- /dev/null +++ b/app/src/main/res/drawable/ic_voice.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_case_upload.xml b/app/src/main/res/layout/activity_case_upload.xml new file mode 100644 index 0000000..fb26c96 --- /dev/null +++ b/app/src/main/res/layout/activity_case_upload.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..481a769 --- /dev/null +++ b/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..866df49 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml new file mode 100644 index 0000000..225dc18 --- /dev/null +++ b/app/src/main/res/layout/activity_map.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml new file mode 100644 index 0000000..b22fabb --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000..5b20e2d --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml new file mode 100644 index 0000000..608b04e --- /dev/null +++ b/app/src/main/res/layout/fragment_mine.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_phone.xml b/app/src/main/res/layout/fragment_phone.xml new file mode 100644 index 0000000..c96a2e9 --- /dev/null +++ b/app/src/main/res/layout/fragment_phone.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_home_recycleview.xml b/app/src/main/res/layout/item_home_recycleview.xml new file mode 100644 index 0000000..1e8cae9 --- /dev/null +++ b/app/src/main/res/layout/item_home_recycleview.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_select_gridview.xml b/app/src/main/res/layout/item_select_gridview.xml new file mode 100644 index 0000000..ccefa5e --- /dev/null +++ b/app/src/main/res/layout/item_select_gridview.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml new file mode 100644 index 0000000..fd99e01 --- /dev/null +++ b/app/src/main/res/layout/line.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000..361be4f --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,37 @@ + +

+ + + + + + + + + + diff --git a/app/src/main/res/mipmap-xhdpi/ajcl.png b/app/src/main/res/mipmap-xhdpi/ajcl.png new file mode 100644 index 0000000..80155d1 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcl.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajcx.png b/app/src/main/res/mipmap-xhdpi/ajcx.png new file mode 100644 index 0000000..dc08c3a --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajcx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhc.png b/app/src/main/res/mipmap-xhdpi/ajhc.png new file mode 100644 index 0000000..29c05fa --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhc.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajhs.png b/app/src/main/res/mipmap-xhdpi/ajhs.png new file mode 100644 index 0000000..3432345 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajhs.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/ajsb.png b/app/src/main/res/mipmap-xhdpi/ajsb.png new file mode 100644 index 0000000..b3175b9 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ajsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/app_logo.png b/app/src/main/res/mipmap-xhdpi/app_logo.png new file mode 100644 index 0000000..c2b13d6 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/app_logo.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/csdb.png b/app/src/main/res/mipmap-xhdpi/csdb.png new file mode 100644 index 0000000..a846014 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/csdb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dashboard.png b/app/src/main/res/mipmap-xhdpi/dashboard.png new file mode 100644 index 0000000..4cbc62f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dashboard.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/dtck.png b/app/src/main/res/mipmap-xhdpi/dtck.png new file mode 100644 index 0000000..c300c32 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/dtck.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/home.png b/app/src/main/res/mipmap-xhdpi/home.png new file mode 100644 index 0000000..556bd0b --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/home.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/jjyj.png b/app/src/main/res/mipmap-xhdpi/jjyj.png new file mode 100644 index 0000000..6a79a21 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/jjyj.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/kssb.png b/app/src/main/res/mipmap-xhdpi/kssb.png new file mode 100644 index 0000000..65217eb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/kssb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/lock.png b/app/src/main/res/mipmap-xhdpi/lock.png new file mode 100644 index 0000000..6f4fa0f --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/lock.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/mine.png b/app/src/main/res/mipmap-xhdpi/mine.png new file mode 100644 index 0000000..708bc09 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/mine.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/phone.png b/app/src/main/res/mipmap-xhdpi/phone.png new file mode 100644 index 0000000..076daa5 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/phone.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/point.png b/app/src/main/res/mipmap-xhdpi/point.png new file mode 100644 index 0000000..4cd125d --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/point.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/sbsb.png b/app/src/main/res/mipmap-xhdpi/sbsb.png new file mode 100644 index 0000000..be75063 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/sbsb.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/tjfx.png b/app/src/main/res/mipmap-xhdpi/tjfx.png new file mode 100644 index 0000000..c2e91cb --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/tjfx.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/user.png b/app/src/main/res/mipmap-xhdpi/user.png new file mode 100644 index 0000000..ad26cec --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/user.png Binary files differ diff --git a/app/src/main/res/mipmap-xhdpi/zgry.png b/app/src/main/res/mipmap-xhdpi/zgry.png new file mode 100644 index 0000000..979e0a3 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/zgry.png Binary files differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..19c8103 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,22 @@ + + + #6200EE + #3700B3 + #03DAC5 + + #03AAC5 + #FFFFFF + #F5F5F5 + #E5E5E5 + #DEDEDE + #D3D3D3 + #C0C0C0 + #A9A9A9 + #808080 + #000000 + + #278DF9 + #E0DEDF + #058CFC + #575757 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..2dddf37 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,14 @@ + + + 16sp + 18sp + + + 10dp + + + 10dp + + + 1px + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..031ee27 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + 移动城管 + + pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..9869d92 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..fafa14f --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/test/java/com/casic/dcms/ExampleUnitTest.java b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java new file mode 100644 index 0000000..66ab075 --- /dev/null +++ b/app/src/test/java/com/casic/dcms/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.casic.dcms; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..96af85d --- /dev/null +++ b/build.gradle @@ -0,0 +1,45 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + + } + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } + google() + jcenter() + maven { url 'https://jitpack.io' } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + authentication { + basic(BasicAuthentication) + } + credentials { + // Do not change the username below. + // This should always be `mapbox` (not your username). + username = 'mapbox' + // Use the secret token you stored in gradle.properties as the password + password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: "" + } + } + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..80e2630 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,20 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true +MAPBOX_DOWNLOADS_TOKEN=pk.eyJ1IjoiMTgzMTA1ODE5MTYiLCJhIjoiY2tuN2hxN3p0MDhjeDJxcW5ja3YyMXNjaiJ9.CsMzaHNCpGTrKkuitQiZlg diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar Binary files differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7754394 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Apr 06 11:01:36 CST 2021 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..bb2607a --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name='DCMS' +include ':app'